package com.zz.demo.utils;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IORuntimeException;
import cn.hutool.core.util.ArrayUtil;
import com.zz.demo.entity.vo.ScanConfigVO;
import org.apache.commons.io.FilenameUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.CollectionUtils;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

public class ScanUtil {

    /**
     * 扫描的判断标志：用于阻止同一时间多个线程来访问同一个传输线路下的扫描文件夹。
     */
    public static final ConcurrentHashMap<String, String> SCAN_CRON_TASK = new ConcurrentHashMap<>();
    private static final Logger log = LoggerFactory.getLogger("ScanUtil");

    /**
     * 根据传入的ScanConfigVO（扫描信息配置类）来进行文件的扫描。
     */
    public static List<File> scanFileByScanConfig(ScanConfigVO scanConfigVO) {
        List<File> files = new ArrayList<>();

        if (scanConfigVO == null) {
            return files;
        }
        String id = scanConfigVO.getId().toString();

        try {
            String scheduleId = SCAN_CRON_TASK.get(id);

            if (scheduleId != null && !scheduleId.isEmpty()) {
                return files;
            }
            String parentDir = scanConfigVO.getScanDir();
            if (parentDir.isEmpty()) {
                log.warn("scanConfigId = " + id + "被扫描的目录为空，结束扫描");
                return files;
            }
            SCAN_CRON_TASK.put(id, id);

            List<File> listOfFiles = new ArrayList<>();
            Date date = new Date();
            long lastTime = date.getTime() - 3 * 1000;

            //根据是否筛选文件格式来进行分批
            if (scanConfigVO.getIsScreenFormat()) {
                //进行筛选
                String screenFormat = scanConfigVO.getScreenFormat();
                //排除筛选格式
                if (screenFormat.isEmpty()) {
                    log.warn("scanConfigId = " + id + "文件筛选格式为空，停止扫描");
                    return files;
                }
                // 去除后缀名中还有.的情况, 如 .txt,.doc
                screenFormat = screenFormat.replaceAll("\\.", "");
                String[] finalFormats = screenFormat.split(",");

                if (scanConfigVO.getIsScanChild()) {
                    //同时扫描子文件夹
                    listOfFiles = FileUtil.loopFiles(parentDir,
                            file -> !file.isDirectory()
                                    && FilenameUtils.isExtension(file.getName(), finalFormats)
                                    && file.lastModified() < lastTime);
                } else {
                    //不扫描子文件夹
                    File[] fileList = FileUtil.ls(parentDir);
                    if (ArrayUtil.isNotEmpty(fileList)) {
                        listOfFiles = Arrays.stream(fileList).filter(
                                file -> !file.isDirectory()
                                        && FilenameUtils.isExtension(file.getName(), finalFormats)
                                        && file.lastModified() < lastTime).collect(Collectors.toList());
                    }
                }

            } else {
                //不进行筛选
                if (scanConfigVO.getIsScanChild()) {
                    //同时扫描子文件夹
                    listOfFiles = FileUtil.loopFiles(parentDir,
                            file -> !file.isDirectory()
                                    && file.lastModified() < lastTime);
                } else {
                    //不扫描子文件夹
                    File[] fileList = FileUtil.ls(parentDir);
                    if (ArrayUtil.isNotEmpty(fileList)) {
                        listOfFiles = Arrays.stream(fileList).filter(
                                file -> !file.isDirectory()
                                        && file.lastModified() < lastTime).collect(Collectors.toList());
                    }
                }
            }
            if (CollectionUtils.isEmpty(listOfFiles)) {
                return files;
            }
            files = listOfFiles.subList(0, Math.min(listOfFiles.size(), 100));
        } catch (IORuntimeException e) {
            e.printStackTrace();
        } finally {
            String scheduleId = SCAN_CRON_TASK.get(id);
            if ( scheduleId != null &&! scheduleId.isEmpty()) {
                SCAN_CRON_TASK.remove(id);
            }

        }
        return files;
    }
}
